﻿// 3669. 淘金.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <memory.h>


using namespace std;
/*
https://www.acwing.com/problem/content/3672/
在一片 n×m的土地上，每一块 1×1的区域里都有一定数量的金子。

这一天，你到这里来淘金，然而当地人告诉你，如果你挖了某一区域的金子，那么该区域上一行的所有区域，下一行的所有区域，
左边相邻的一个区域，右边相邻的一个区域的金子就都不能被允许挖了。

那么问题来了：你最多能淘金多少？

输入格式
输入包含多组测试数据。

每组数据第一行包含两个整数 n,m。

接下来 n行，每行 m个数，表示每个区域的金子数量。

输出格式
每组数据输出一行结果，表示最多可以得到的金子数量。

数据范围
1≤n,m≤200
,
每个区域内的金子数量 [0,1000]
。
输入最多包含 100组数据。

输入样例：
4 6
11 0 7 5 13 9
78 4 81 6 22 4
1 40 9 34 16 10
11 22 0 33 39 6
输出样例：
242
*/

const int N = 210;
int dpRow[N];
int dpCol[N];

int area[N][N];
int n, m;

void CalcDpRow(int x) {
	int dp[N]; memset(dp, 0, sizeof dp);
	dp[1] = area[x][1];
	for (int i = 2; i <= m; i++) {
		dp[i] = max(dp[i - 1], dp[i - 2] + area[x][i]);
	}

	dpRow[x] = dp[m];
}

void CalcDp() {
	int dp[N]; memset(dp, 0, sizeof dp);
	dp[1] = dpRow[1];

	for (int i = 2; i <= n;i++) {
		dp[i] = max(dp[i - 1], dp[i - 2] + dpRow[i]);
	}

	cout << max(dp[n], dp[n - 1]) << endl;
	return;
}


int main()
{	
	while (cin >> n >> m) {
		memset(dpRow, 0, sizeof dpRow);
		memset(dpCol, 0, sizeof dpCol);
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				cin >> area[i][j];
			}
		}

		for (int i = 1; i <= n; i++) {
			CalcDpRow(i);
		}


		CalcDp();
	}

	return 0;
}

 